package com.github.baichuan.application.scaffold.rest.domain.authorization;

import com.github.baichuan.application.scaffold.rest.domain.application.ApplicationService;
import com.github.baichuan.application.scaffold.rest.domain.identity.ApplicationMember;
import com.github.baichuan.application.scaffold.rest.domain.identity.ApplicationMemberService;
import com.github.baichuan.application.scaffold.rest.jpa.authorization.ResourceRepository;
import com.github.baichuan.web.dto.Result;
import com.github.baichuan.web.error.NoSuchEntityException;
import com.github.baichuan.application.scaffold.rest.domain.application.Application;
import com.github.baichuan.utils.SnowFlake;
import lombok.NonNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

@Service
@Transactional(rollbackFor = Exception.class)
public class ResourceService {
    @Autowired
    public ResourceService(ResourceRepository resourceRepository,
                           ApplicationService applicationService,
                           ApplicationMemberService applicationMemberService,
                           SnowFlake snowFlake) {
        this.resourceRepository = resourceRepository;
        this.applicationService = applicationService;
        this.applicationMemberService = applicationMemberService;
        this.snowFlake = snowFlake;
    }

    private ResourceRepository resourceRepository;
    private ApplicationService applicationService;
    private ApplicationMemberService applicationMemberService;
    private SnowFlake snowFlake;

    public Resource find(String id) {
        Optional<Resource> optional = resourceRepository.findById(id);
        return optional.orElseThrow(() -> new NoSuchEntityException("功能或菜单id不存在"));
    }

    public Resource find(String application, String id){
        Resource resource = find(id);
        if(!resource.getApplication().getCode().equals(application)){
            throw new NoSuchEntityException("菜单资源不存在");
        }
        return resource;
    }

    public List<Resource> findByApplication(String applicationCode){
        Application application = applicationService.findByCode(applicationCode);
        return resourceRepository.findByApplication(application);
    }

    /**
     * 获取用户可以向他人授权的资源清单
     * @param applicationCode
     * @param memberUid
     * @return
     */
    public List<Resource> getAssignable(@NonNull String applicationCode, @NonNull String memberUid) {
        ApplicationMember member = applicationMemberService.find(applicationCode, memberUid);
        if ("ADMIN".equals(member.getMemberType())) {
            Application application = applicationService.findByCode(applicationCode);
            return resourceRepository.findByApplication(application);
        } else {
            return resourceRepository.getAuthorized(applicationCode, memberUid);
        }
    }

//    public Result add(String applicationCode, ResourceForm form) {
//        Application application = applicationService.find(applicationCode.trim());
//        Resource parent = null;
//        if (null != form.getParentId())
//            parent = find(form.getParentId());
//
//        if(parent != null && !parent.getApplication().getCode().equals(application.getCode())){
//            return Result.fail("父资源应用代码与平台代码不匹配");
//        }
//
//        Optional<Resource> duplication = resourceRepository.findById(application, form.getCode().trim());
//        if (duplication.isPresent()) {
//            return Result.fail("资源代码重复");
//        }
//
//        Resource resource = new Resource();
//        resource.setId(snowFlake.nextBase62Id().substring(2));
//        resource.setApplication(application);
//        merge(form, resource);
//
//        if (null != form.getParentId()) {
//            resource.setParent(parent);
//        }
//        resourceRepository.save(resource);
//
//        return Result.success("菜单保存成功", resource.getId());
//    }

//    private void merge(ResourceForm from, Resource to) {
//        to.setName(from.getName().trim());
//        to.setCode(from.getCode().trim());
//        to.setKind(from.getKind());
//        to.setRoute(StringUtils.isNotBlank(from.getRoute()) ? from.getRoute().trim() : "");
//        to.setPath(StringUtils.isNotBlank(from.getPath()) ? from.getPath().trim() : "");
//        to.setIconCss(from.getIconCss());
//        to.setSort(from.getSort());
//    }

//    public Result edit(String applicationCode, String id, ResourceForm form) {
//        Application application = applicationService.find(applicationCode.trim());
//
//        Optional<Resource> duplication = resourceRepository.findByCode(application, form.getCode().trim());
//        if (duplication.isPresent() && duplication.get().getId().equals(id)) {
//            return Result.fail("资源代码重复");
//        }
//
//        Resource resource = find(id);
//        if (!resource.getApplication().getCode().equals(application.getCode())) {
//            return Result.fail("平台编码错误");
//        }
//        merge(form, resource);
//        if (form.getParentId() != null) {
//            Resource parent = find(form.getParentId());
//            if (!resource.checkCycle(parent)) {
//                resource.setParent(parent);
//            } else {
//                return Result.fail("父菜单不能是当前菜单及当前菜单的子菜单");
//            }
//        }
//
//        resourceRepository.save(resource);
//        return Result.success("菜单保存成功");
//    }

    public Result remove(String application, String id){
        Resource resource = find(application, id);
        if(resourceRepository.getChildren(resource).size() > 0){
            return Result.fail("请先删除下级资源");
        }
        resourceRepository.delete(resource);

        // 删除角色授权
        resourceRepository.removeRolePrivilege(id);

        return Result.success("删除成功");
    }
}
